﻿/*              Copyright(c) 2008 Dave Sexton              *
 * http://www.codeplex.com/DocProject                      *
 * http://www.codeplex.com/DocProject/Project/License.aspx *
 ***********************************************************/
using System;
using System.Collections.Generic;
using System.Text;
using DaveSexton.DocToMaml.Maml;
using DaveSexton.DocToMaml.Extensions;

namespace DaveSexton.DocToMaml
{
	internal sealed class RuleContainer : RuleCollection, IRuleContainer
	{
		#region Public Properties
		public IRuleContainer DefaultRules
		{
			get
			{
				return defaultRules;
			}
			set
			{
				if (defaultRules != null)
					defaultRules.CollectionChange -= defaultRules_CollectionChange;

				defaultRules = value;

				if (defaultRules != null)
					defaultRules.CollectionChange += defaultRules_CollectionChange;
			}
		}
		#endregion

		#region Private / Protected
		private IRuleContainer defaultRules;
		#endregion

		#region Constructors
		/// <summary>
		/// Constructs a new instance of the <see cref="RuleContainer" /> class.
		/// </summary>
		public RuleContainer()
		{
		}
		#endregion

		#region Methods
		public RuleCollection GetRules(RuleAction action)
		{
			RuleCollection list = new RuleCollection();

			GetRulesWithInheritance(list, this, action);

			return list;
		}

		private static void GetRulesWithInheritance(RuleCollection list, IRuleContainer container, RuleAction action)
		{
			foreach (IRule rule in container)
			{
				if (rule.Action == action && !list.Contains(rule, RuleEqualityComparer.Default))
					list.Add(rule);
			}

			if (container.DefaultRules != null)
				GetRulesWithInheritance(list, container.DefaultRules, action);
		}

		public RuleCollection GetRules(RuleAction action, RuleMatchKind matchKind)
		{
			RuleCollection list = new RuleCollection();

			GetRulesWithInheritance(list, this, action, matchKind);

			return list;
		}

		private static void GetRulesWithInheritance(RuleCollection list, IRuleContainer container, RuleAction action, RuleMatchKind matchKind)
		{
			foreach (IRule rule in container)
			{
				if (rule.Action == action && rule.MatchKind == matchKind && !list.Contains(rule, RuleEqualityComparer.Default))
					list.Add(rule);
			}

			if (container.DefaultRules != null)
				GetRulesWithInheritance(list, container.DefaultRules, action, matchKind);
		}
		#endregion

		#region Event Handlers
		private void defaultRules_CollectionChange(object sender, EventArgs e)
		{
			OnCollectionChange(e);
		}
		#endregion
	}
}
